{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<p style=\"text-align: center;font-size: 33px;font-weight:bold;\"> <span style=\"color:DarkGoldenrod\">&lt;&lt;结构体与共用体 &gt;&gt;</span></p>\n",
    "<p style=\"text-align: center;font-size: 25px;font-weight:bold;\"> <span style=\"color:Goldenrod\">&lt;&lt; Programming Basics using C Language  &gt;&gt;</span></p>\n",
    "<p style=\"text-align: right; font-size:15px; font-weight:normal\">----学而时习之，不亦乐乎？</p>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 结构体与共同体\n",
    "* **结构体的基本定义方式：** &nbsp;&nbsp;&nbsp;&nbsp;struct{char* name;float height;int age;...}&nbsp;&nbsp; people；\n",
    "* **含义：** 定义了一个命名为people的结构体变量(对象)，该变量有name,height,age等属性。\n",
    "* **共用体(联合)的定义方式：**&nbsp;&nbsp;&nbsp;&nbsp;union{float fval;int ival;double dval;}&nbsp;&nbsp;udata;\n",
    "* **含义：** 定义了一个命名为person的共用体(联合)变量，该变量可以有name,height,age等属性，各种属性共用同一块内存空间，相互影响。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```C\n",
    "//三种特殊数据类型：\n",
    "//1. 枚举\n",
    "enum{Mon,Tue,Wed,Thr,Fri,Sat,Sun} WeekDay; //WeekDay 变量名。\n",
    "//2. 结构\n",
    "typedef struct{char* name;int age;float height;int graduate;int sex;} People;  //服务于数据结构的定义与实现。\n",
    "People p;\n",
    "\n",
    "struct People {char* name;int age;float height;int graduate;int sex;} people;\n",
    "//3. 联合结构\n",
    "union{float fval;int ival;double dval;} udata;\n",
    "//注意结构体与结构、联合结构的区别（逗号与分号）。\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 类型定义（typedef）"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* **为基本数据类型添加别名**  &nbsp;&nbsp;&nbsp;typedef&nbsp;&nbsp;int&nbsp;&nbsp;char32;&nbsp;&nbsp;char32&nbsp;&nbsp;c;....\n",
    "* **为特殊数据类型添加别名**  &nbsp;&nbsp;&nbsp;typedef&nbsp;&nbsp;struct(/union){char*&nbsp;&nbsp;name;float&nbsp;&nbsp;height;int&nbsp;&nbsp;age;...}&nbsp;&nbsp;people；\n",
    "* **为函数指针类型添加别名**  &nbsp;&nbsp;&nbsp;typedef&nbsp;&nbsp;int&nbsp;&nbsp;(* &nbsp;&nbsp;pfunc)(int&nbsp;&nbsp;a,int&nbsp;&nbsp;b);\n",
    "* **为定长数组类型添加别名**  &nbsp;&nbsp;&nbsp;typedef&nbsp;&nbsp;char&nbsp;&nbsp;wchar\\[2\\];\n",
    "* **为数组指针类型添加别名**  &nbsp;&nbsp;&nbsp;typedef&nbsp;&nbsp;int&nbsp;&nbsp;(* &nbsp;&nbsp;p)\\[3\\];\n",
    "* **总结：** &nbsp;&nbsp;&nbsp;&nbsp;怎么定义变量，怎么定义类型。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Size of defined type wchar is 2!\n",
      "Size of defined type people is 16!\n",
      "Size of defined type person is 8!\n"
     ]
    }
   ],
   "source": [
    "#include <stdio.h>\n",
    "typedef int char32;\n",
    "typedef struct{char* name;float height;int age;} people;\n",
    "typedef union{char* name;float height;int age;} person;\n",
    "typedef int (* pfunc)(int a, int b);\n",
    "typedef char wchar[2];\n",
    "typedef int (* p3i)[3];\n",
    "int main(){\n",
    "printf(\"Size of defined type wchar is %ld!\\n\",sizeof(wchar));\n",
    "printf(\"Size of defined type people is %ld!\\n\",sizeof(people));\n",
    "printf(\"Size of defined type person is %ld!\\n\",sizeof(person));    \n",
    "//堂上作业：打印出上述剩余定义类型的长度。     \n",
    "}\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 结构体内变量访问 \n",
    "* **结构体变量名. 变量名**\n",
    "* **结构体指针名->变量名**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "struct People{int a;int b;int c; float d; ............................};\n",
    "struct People p;\n",
    "struct People* pp; pp=&p;\n",
    "pp->a;pp->b;\n",
    "\n",
    "People pa;\n",
    "func(struct People* p){\n",
    "    p->a;\n",
    "}\n",
    "//func(pa);  // \n",
    "func(&pa);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 结构体的函数传参\n",
    "*  **结构体赋值** &nbsp;&nbsp;&nbsp;&nbsp; people people1 = people2;(运行时新建一个结构体people1, 将people2中每一个属性赋值到people1)\n",
    "*  **结构体传参** &nbsp;&nbsp;&nbsp;&nbsp; 定义函数func(people p1,people p2)，直接调用函数func(pepole1,people2)相当于在func的函数栈执行p1=people1,p2=people2;当结构体people过大时，时间与内存开销过大。\n",
    "*  **结构体传址** &nbsp;&nbsp;&nbsp;&nbsp; 可改为定义函数func(people* p1,people* p2)，调用函数func(&people1,&people2);\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 结构体的自引定义"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "```C\n",
    "struct Node{\n",
    "            int val;                  //代表节点数据\n",
    "            struct Node*  left;       //指向左子节点\n",
    "            struct Node* right;       //指向右子节点\n",
    "            } root;                   //定义一个树节点。\n",
    "            \n",
    "typedef struct Node{\n",
    "                   int val;\n",
    "                   struct Node* left;\n",
    "                   struct Node* right;\n",
    "                   } Node;\n",
    "}\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 位字段"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```C\n",
    "struct bitpos{\n",
    "             unsigned int  low: 2;// n位长\n",
    "             unsigned int  mid: 1;\n",
    "             unsigned int high: 1;\n",
    "             }\n",
    "//C语言中的特殊定义， 一种没有物理地址的变量声明。\n",
    "//可用于表达程序中的多种状态。\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#### 内存申请\n",
    "* T* t=(T* )malloc(sizeof(T))  // 向操作系统申请内存。\n",
    "* free(t);                     // 内存释放。     "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 链表"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![链表](./Resources/LinkList.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```C\n",
    "//基本类型定义,从整体结构中的单个节点出发\n",
    "struct LinkList{\n",
    "    struct Data      data;                       // 单个元素中的数据  \n",
    "    struct LinkList* next;                       // 指向表中下一个元素\n",
    "} linklist；                                     // 整体上看定义了一个LinkList类型的结构体变量linklist.\n",
    "      \n",
    "//相关操作\n",
    "//1. 向表尾添加数据    \n",
    "void append_list(struct LinkList* list,struct Data& data){\n",
    "if(list==NULL) return;\n",
    "if(list->next!=NULL)     \n",
    "for(struct LinkList* c=list->next;c->next!=NULL;c=c->next);                         //找到表尾,预留表头\n",
    "    struct LinkList* new=(struct LinkList*)malloc(sizeof(LinkList));                //申请新节点的内存空间\n",
    "    new->Data=Data;                                                                 //在新节点中添加数据\n",
    "    c->next=new;                                                                    //接入新数据到表尾\n",
    "}\n",
    "//2. 按要求查找表节点    \n",
    "struct LinkList* find(struct LinkList* list,int number){\n",
    "for(struct LinkList* c=list;(c->data).no!=number&&c->next!=null;c=c->next);\n",
    "if((c->data).no!=number) return NULL; //确定达到表尾且表尾数据不符合要求。\n",
    "    else return c;\n",
    "}\n",
    "//2.1 按要求查找表节点的前一个元素\n",
    "struct LinkList* find(struct LinkList* list,int number){\n",
    "if(list==NULL||list->next==NULL) return NULL;\n",
    "for(struct LinkList* c;(c->next).data.no!=number;c=c->next);\n",
    "if(c->next==NULL) return NULL; //确定达到表尾\n",
    "else return c;\n",
    "}\n",
    "\n",
    "//3. 删除表中节点p的下一个节点。\n",
    "void del_node(struct LinkList* p){\n",
    "struct LinkList* c=p->next;\n",
    "    if(c==NULL) return;  //表尾节点没有下一个节点\n",
    "    else{\n",
    "    p->next =c->next;\n",
    "    free(c);    \n",
    "    }\n",
    "}\n",
    "//4. 销毁整个链表\n",
    "void destory_list(struct LinkList* list){\n",
    "    if(list==NULL) return;\n",
    "    while(list->next!=null) del_node(list);\n",
    "    free(list);\n",
    "}\n",
    "\n",
    "int main(){\n",
    "for(int i=0;i<10;i++){\n",
    "struct LinkList* p = (struct LinkList*)malloc(sizeof(LinkList)); \n",
    "scanf(\"Please input number：%u\\n\",&((p->data).no));\n",
    "scanf(\"Please input name:%s\\n\",(p->data).name); \n",
    "append_list(linklist,p);\n",
    "    //......scanf其他\n",
    "}\n",
    "\n",
    "//其他操作。\n",
    "}\n",
    "\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 栈"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```C\n",
    "//基本类型定义\n",
    "#define MaxE 200\n",
    "typedef struct {                                            //重要数据结构，先进后出\n",
    "              struct Data datas[MaxE]; \n",
    "              int top;    \n",
    "} Stack;                \n",
    "\n",
    "Stack t;\n",
    "\n",
    "//相关操作（类型行为）  // int a; int& b=a;  \n",
    "Data pop_stack(Stack& s){                         // 弹栈\n",
    "   return(s.data[s.top--]);                              // 关键语句\n",
    "}\n",
    "\n",
    "Data d = pop_stack(t);\n",
    "\n",
    "void push_stack(Stack& s,  Data& data){      // 压栈\n",
    "    s.datas[++s.top]=data;                               // 关键语句\n",
    "}\n",
    "int is_Stack_Empty(Stack& s){\n",
    "if(s.top<0) return 1;\n",
    "else return 0;\n",
    "}\n",
    "                                         \n",
    "int main(){\n",
    "struct Stack st;                                        //声明变量,常规类型声明下需要添加struct关键字， \n",
    "struct Data data;data.feature1=......;                  // 生明数据变量、数据变量赋值。\n",
    "push_stack(st,data);                                    // 压数据入栈    \n",
    "//codes....\n",
    "Data data_c= pop_stack(st);                             // 弹除栈顶元素  \n",
    "//codes....\n",
    "}\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 作业\n",
    "* 1.简述C语言中**变量**的定义方式，包括基本数据类型、数组、特殊数据类型。\n",
    "* 2.简述以下四种函数参数类型定义的区别： int func_a(**int a**)、 int func_b(**int* b**)、int func_c(**int& c**)、int func_d(**int c\\[\\]**)的区别。 \n",
    "* 3.简述关键字**return**在函数中的作用。\n",
    "* 4.什么是**递归函数**，递归函数的设计过程中应注意什么？递归函数的好处是什么？\n",
    "* 5.简述以下三种结构体定义方式的区别。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```C\n",
    "struct {int a;float b;char* c;} st;\n",
    "struct ST{int a;floatb;char* c;};\n",
    "typedef {int a;float b;char* c;} ST;\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* 6.该怎样设计**以结构体作为参数类型**的**函数**？给出具体代码。\n",
    "* 7.什么是结构体的**自引定义**？\n",
    "* 8.完善本课件中数据结构**栈**的定义，成功实现数据的压栈与弹栈。\n",
    "* **注意：**本次作业简述题中如果有雷同情况，全部不予记录成绩。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "int d;\n",
    "int& c=d;\n",
    "int func(int* c){ // C++特有的同名变量定义方式。\n",
    "    c与d是同名关系。\n",
    "        (*c)  看作实参d.\n",
    "};\n",
    "b=func(d). \n",
    "    \n",
    "int func_d(int c[]){\n",
    "    c=0xaabbcc0090;\n",
    "}\n",
    "int func_d(int* c){\n",
    "    c=0xABD000EEEE;\n",
    "};//   \n",
    "\n",
    "struct{char c[20];} st;\n",
    "st.c=\"nime\";\n",
    "st.c[1]='a';\n",
    "\n",
    "void modify_struct(ST* st){\n",
    "    print(\"\",st.name).....\n",
    "};\n",
    "int main(){\n",
    "    St st1;\n",
    "    print_strcut(st1);    St st=st1;//   st.name=st1.name;  st.no=st1.no........\n",
    "}"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "C",
   "language": "c",
   "name": "c"
  },
  "language_info": {
   "file_extension": ".c",
   "mimetype": "text/plain",
   "name": "c"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
